﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>对象 - 方法 &amp; 属性 | AutoHotkey v2</title>
<meta name="description" content="对象 is the basic class from which other AutoHotkey 对象 classes derive." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>对象</h1>

<p><strong>对象(对象)</strong> 是派生其他 AutoHotkey 对象类的基本类. 每个 对象 实例包含以下内容:</p>
<ul>
  <li>自己的属性: 属于这个特定对象的一组属性.</li>
  <li>自己的方法: 属于这个特定对象的一组方法.</li>
  <li>基对象, 从其继承属性和方法.</li>
</ul>
<p>属性分为值属性和动态属性. 值属性只包含一个值. 动态属性不包含值, 而是在访问时调用 <em>getter</em> 或 <em>setter</em> 函数. 派生对象可以覆盖 <em>getter</em> 或 <em>setter</em>(最简单的方法是在类中定义它们).</p>
<p>下面的文档使用 <code>Obj</code> 作为 对象 的任何实例的占位符.</p>
<p>所有 对象 的实例都基于 <code>对象.Prototype</code>, 而其又基于 <a href="Any.htm">Any 原型</a>. 除了从 Any 继承的方法和属性外, 对象 还具有以下预定义的方法和属性:</p>
<p><strong>方法:</strong></p>
<ul>
	<li><a href="#Clone">复制</a></li>
  <li><a href="#DefineMethod">定义方法</a></li>
  <li><a href="#DefineProp">定义属性</a></li>
  <li><a href="#DeleteMethod">删除方法</a></li>
  <li><a href="#DeleteProp">删除属性</a></li>
  <li><a href="#GetOwnPropDesc">获取属性描述</a></li>
  <li><a href="#HasOwnMethod">包含方法</a></li>
  <li><a href="#HasOwnProp">包含属性</a></li>
  <li><a href="#OwnMethods">枚举方法</a></li>
  <li><a href="#OwnProps">枚举属性</a></li>
</ul>
<p><strong>属性:</strong></p>
<ul>
	<li><a href="#Base">Base</a></li>
</ul>
<p><strong>函数:</strong></p>
<ul>
  <li><a href="#Object">对象</a>: 从属性 "名, 值" 对列表中创建一个对象.</li>
	<li><a href="#SetBase">设置父对象</a>: 设置对象的<a href="../Objects.htm#delegation">基对象</a>.</li>
  <li><a href="#GetCapacity">获取对象容量</a>, <a href="#SetCapacity">设置对象容量</a>: 检索或设置对象所包含属性的容量.</li>
  <li><a href="#OwnPropCount">属性总数</a>: 检索对象包含的自有属性的数量.</li>
  <li>ObjHasOwnProp, 枚举方法, 枚举属性: 等同于相应的预定义方法, 但不能被覆盖.</li>
</ul>

<h2 id="Methods">方法</h2>

<div class="methodShort" id="Clone"><h2>复制</h2>
<p>返回对象的一个浅拷贝.</p>
<pre class="Syntax">复制 := Obj.<span class="func">复制</span>()</pre>
<p>对象拥有的每个属性或方法都被复制到副本中. 对象 <em>引用</em> 被复制(就像普通的赋值一样), 而不是对象本身; 换句话说, 如果属性包含对对象的引用, 则副本将包含对同一对象的引用.</p>
<p>动态属性被复制, 而不是调用.</p>
<p>副本具有与原始对象相同的基对象.</p>
</div>

<div class="methodShort" id="DefineMethod"><h2>定义方法</h2>
<p>定义一个新的方法.</p>
<pre class="Syntax">Obj.<span class="func">定义方法</span>(Name, MethodFunc)</pre>
<dl>
  <dt>Name</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>方法的名称.</p>
  </dd>
  <dt>MethodFunc</dt>
  <dd>
    <p>类型: <a href="Functor.htm">函数对象</a></p>
    <p>方法的实现. 函数必须接受至少一个参数, 该参数接收对方法调用的目标对象的引用. 当方法由类定义创建时, 将自动使用名称 <code>this</code> 定义此参数.</p>
  </dd>
  <dt>返回 Value</dt>
  <dd>
    <p>目标对象(<em>Obj</em>).</p>
  </dd>
</dl>
<p>新方法归 <em>Obj</em> 所有, 但是任何以 <em>Obj</em> 为基的对象都可以继承. 如果 <em>Obj</em> 是一个类, 则新方法仅适用于类本身和子类(即它是静态的). 要为类的所有实例定义一个方法, 让 <em>Obj</em> 为类的 <code>Prototype</code>.</p>
</div>

<div class="methodShort" id="DefineProp"><h2>定义属性</h2>
<p>定义一个新的自有属性.</p>
<pre class="Syntax">Obj.<span class="func">定义属性</span>(Name, Desc)</pre>
<dl>
  <dt>Name</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>属性的名称.</p>
  </dd>
  <dt>Desc</dt>
  <dd>
    <p>类型: 对象</p>
    <p>具有以下自身属性之一对象, 或同时具有 <em>Get</em> 和 <em>Set</em>:</p>
    <p><code>Get</code>: 获取属性值时调用的<a href="Functor.htm">函数对象</a>.</p>
    <p><code>Set</code>: 属性被赋值时调用的<a href="Functor.htm">函数对象</a>. 第二个参数是要分配的值.</p>
    <p><code>Value</code>: 要赋值该属性的任何值.</p>
  </dd>
  <dt>返回 Value</dt>
  <dd>
    <p>目标对象(<em>Obj</em>).</p>
  </dd>
</dl>
<p>该方法可用于将值属性转换为动态属性, 反之亦然, 但不可能同时指定一个值和一个 getter/setter.</p>
<p>如果只定义了 <em>Get</em> 或 <em>Set</em> 未定义, 则对应的可以从基对象中继承. 如果 <em>Get</em> 未定义, 则该属性可以返回从基继承的值. 如果 <em>Set</em> 在此对象和所有基对象中均未定义, 则该属性为只读(尝试设置该属性会抛出异常).</p>
<p>与方法一样, <em>Get</em> 或 <em>Set</em> 的第一个参数是 <code>this</code>(目标对象). 对于 <em>Set</em>, 第二个参数是 <code>value</code>(要被赋予的值). 这些参数由类中的方法和属性定义自动定义, 但是如果使用常规函数, 则必须显式定义.</p>
<p>计算函数对象的 <code>MaxParams</code> 和 <code>IsVariadic</code> 属性, 以确定该属性是否可以接受参数. 如果 <em>get</em> 的 <code>MaxParams</code> 为 1, 或 <em>set</em> 的 <code>MaxParams</code> 为 2, 并且 <code>IsVariadic</code> 为 false 或未定义, 则属性不能接受参数; 它们被转发到由 <em>get</em> 返回的对象的 <a href="../Objects.htm#__Item">__Item</a> 属性.</p>
</div>

<div class="methodShort" id="DeleteMethod"><h2>删除方法</h2>
<p>删除对象拥有的方法.</p>
<pre class="Syntax">Obj.<span class="func">删除方法</span>(Name)</pre>
<dl>
  <dt>Name</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>方法名. 如果对象不拥有此名称的方法, 则抛出异常.</p>
  </dd>
</dl>
</div>

<div class="methodShort" id="DeleteProp"><h2>删除属性</h2>
<p>删除对象拥有的属性.</p>
<pre class="Syntax">Obj.<span class="func">删除属性</span>(Name)</pre>
<dl>
  <dt>Name</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>属性名.</p>
  </dd>
  <dt>返回值</dt>
  <dd><p>删除属性的值(如果没有则为空).</p></dd>
</dl>
</div>

<div class="methodShort" id="GetOwnPropDesc"><h2>获取属性描述</h2>
<p>返回给定自有属性的描述符, 兼容于 <a href="#DefineProp">定义属性</a>.</p>
<pre class="Syntax">Obj.<span class="func">获取属性描述</span>(Name)</pre>
<dl>
  <dt>Name</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>属性名.</p>
  </dd>
  <dt>返回值</dt>
  <dd>
    <p>类型: 对象</p>
    <p>对于动态属性, 返回值是一个新的对象, 它具有以下一个或两个自有属性:<br>
    <code>Get</code>: 如果在<em>Obj</em> 有定义, 则在检索属性值时调用的<a href="Functor.htm">函数对象</a>.<br>
    <code>Set</code>: 如果在<em>Obj</em> 有定义, 则在属性被赋值时调用的<a href="Functor.htm">函数对象</a>.</p>
    <p>对于值属性, 返回值是一个新对象, 其属性名为 <code>Value</code>. 在这种情况下, <code>Obj.获取属性描述(Name).Value == Obj.%Name%</code>.</p>
  </dd>
</dl>
<p></p>
<p>除非调用 <a href="#DefineProp">定义属性</a>, 否则修改返回的对象对 <em>Obj</em> 没有影响.</p>
<p>如果 <em>Obj</em> 不拥有该名称的属性, 则抛出异常. 脚本可以通过检查 <code>not desc.包含属性("Value")</code> 来确定一个属性是否是动态的, 其中 <em>desc</em> 是 获取属性描述 的返回值.</p>
</div>

<div class="methodShort" id="HasOwnMethod"><h2>包含方法</h2>
<pre class="Syntax">Obj.<span class="func">包含方法</span>(Name)</pre>
<p>如果对象拥有该名称的方法, 则返回 true, 否则返回 false.</p>
</div>

<div class="methodShort" id="HasOwnProp"><h2>包含属性</h2>
<pre class="Syntax">Obj.<span class="func">包含属性</span>(Name)</pre>
<p>如果对象拥有该名称的属性, 则返回 true, 否则返回 false.</p>
<p>该方法的默认实现也被定义为一个函数: <code>ObjHasOwnProp(Obj, Name)</code>.</p>
</div>

<div class="methodShort" id="OwnMethods"><h2>枚举方法</h2>
<p>枚举对象拥有的方法.</p>
<pre class="Syntax">遍历 Name <span class="optional">, MethodFunc</span> in Obj.<span class="func">枚举方法</span>()</pre>
<p>返回一个新的<a href="Enumerator.htm">枚举器</a>. 该枚举器通常直接传递给 <a href="../commands/For.htm">遍历-loop</a>, 循环的每次迭代都调用一次枚举器. 每次对枚举器的调用都会返回下一个方法名和/或其实现函数. 遍历-loop 的变量对应于枚举器的参数, 它们是:</p>
<dl>
  <dt>Name</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>方法名.</p>
  </dd>
  <dt>MethodFunc</dt>
  <dd>
    <p>类型: <a href="Functor.htm">函数对象</a></p>
    <p>方法的实现. 这可以是由类定义创建的 <a href="Func.htm">检索函数</a>, 也可以是先前传递给 <a href="#DefineMethod">定义方法</a> 的对象.</p>
  </dd>
</dl>
<p>该方法的默认实现也被定义为一个函数: <code>枚举方法(Obj)</code>.</p>
</div>

<div class="methodShort" id="OwnProps"><h2>枚举属性</h2>
<p>枚举对象自有的属性.</p>
<pre class="Syntax">遍历 Name <span class="optional">, Value</span> in Obj.<span class="func">枚举属性</span>()</pre>
<p>返回一个新的<a href="Enumerator.htm">枚举器</a>. 该枚举器通常直接传递给 <a href="../commands/For.htm">遍历-loop</a>, 循环的每次迭代都调用一次枚举器. 每次对枚举器的调用都会返回下一个属性名和/或其值. 遍历-loop 的变量对应于枚举器的参数, 它们是:</p>
<dl>
  <dt>Name</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>属性名.</p>
  </dd>
  <dt>Value</dt>
  <dd>
    <p>属性的值.</p>
    <p>如果该属性具有 getter 方法, 则将调用该方法以获得该值(除非省略 <em>Value</em>).</p>
  </dd>
</dl>
<p>动态属性包含在枚举中. 但是:</p>
<ul>
  <li>因为只有对象自有的属性才会被枚举, 所以属性必须在 <em>Obj</em> 中直接定义.</li>
  <li>如果只指定了第一个变量, 则返回属性的名称, 不调用它的 getter.</li>
  <li>如果指定了两个变量, 枚举器会尝试调用属性的 getter 来检索值.
    <ul>
      <li>如果 getter 需要参数, 则跳过该属性.</li>
      <li>如果 <em>Obj</em> 只包含一个 setter, 而不包含这个属性的 getter, 则跳过.</li>
      <li>如果 <em>Obj</em> 是一个类原型对象, 则不应该(在某些情况下不能) 调用 getter; 所以跳过该属性.</li>
      <li>如果 getter 抛出一个异常, 它将被传播(而不是被抑制). 调用者只有在保留了对枚举器的引用的情况下, 才能继续对下一个属性进行枚举(例如, 如果直接将枚举器传递给 遍历-loop, 则不能继续枚举, 因为在这种情况下, 当 遍历-loop 中止时, 枚举器会被释放).</li>
    </ul>
  </li>
</ul>
<p>要在不调用属性 getters 的情况下枚举自有的属性, 只需向 遍历-loop 或 枚举器传递一个变量. <a href="#GetOwnPropDesc">获取属性描述</a> 可以用来区分值属性和动态属性, 同时也可以检索值或 getter/setter.</p>
<p>该方法的默认实现也被定义为一个函数: <code>枚举属性(Obj)</code>.</p>
</div>

<h2 id="Properties">属性</h2>

<div class="methodShort" id="Base"><h2>Base</h2>
<p>检索或设置对象的<a href="../Objects.htm#delegation">基对象</a>.</p>
<pre class="Syntax">BaseObj := Obj.Base</pre>
<pre class="Syntax">Obj.Base := BaseObj</pre>
<p><em>BaseObj</em> 必须是一个对象.</p>
<p>如果给新基赋值会改变对象的原生类型, 则抛出异常. 对象的原生类型由属于内置类的最近原型对象决定, 例如 <code>对象.Prototype</code> 或 <code>数组.Prototype</code>. 例如, 数组 的实例必须始终直接或间接地从 <code>数组.Prototype</code> 派生.</p>
<p>属性和方法是从基对象动态继承的, 因此更改对象的基也会更改哪些可用继承的属性和方法.</p>
<p>属性继承于 <a href="Any.htm">Any</a>; 但是, 只能为 对象 的实例设置它.</p>
<p>另请参阅: <a href="Any.htm#GetBase">获取父对象</a>, <a href="#SetBase">设置父对象</a></p>
</div>

<h2 id="Functions">函数</h2>

<div class="methodShort" id="Object"><h2>对象</h2>
<p>从属性的 "名称, 值" 对的列表中创建一个 对象.</p>
<pre class="Syntax">Obj := <span class="func">对象</span>(<span class="optional">Name, Value, Name2, Value2, ...</span>)</pre>
<p>这相当于用 <code>Obj := 对象.New()</code> 创建一个对象, 然后用 <code>Obj.%Name% := Value</code> 设置每个属性.</p>
<p>如果在脚本中定义了这个名称的函数, 那么在同一作用域中的任何对象文字(如 <code>{}</code>) 都会产生对该函数的调用, 而不是默认的 对象 函数. 对象文字中的属性名不加引号, 所以例如, <code>{a: b}</code> 等同于 <code>对象("a", b)</code>.</p>
</div>

<div class="methodShort" id="SetBase"><h2>设置父对象</h2>
<p>设置对象的<a href="../Objects.htm#delegation">基对象</a>.</p>
<pre class="Syntax"><span class="func">设置父对象</span>(Obj, BaseObj)</pre>
<p>不调用<a href="../Objects.htm#Meta_Functions">元-函数</a>或<a href="../Objects.htm#Custom_Classes_property">属性函数</a>. 覆盖 <a href="#Base">Base</a> 属性不会影响此函数的行为.</p>
<p>如果 <em>Obj</em> 或 <em>BaseObj</em> 的类型不正确, 则抛出异常.</p>
<p>另请参阅: <a href="Any.htm#GetBase">获取父对象</a>, <a href="#Base">Base 属性</a></p>
</div>

<div class="methodShort" id="OwnPropCount"><h2>属性总数</h2>
<p>返回对象拥有的属性的数量.</p>
<pre class="Syntax">Count := <span class="func">属性总数</span>(Obj)</pre>
</div>

<div class="methodShort" id="SetCapacity"><h2>设置对象容量</h2>
<p>设置对象内部自有属性的当前容量.</p>
<pre class="Syntax"><span class="func">设置对象容量</span>(Obj, MaxProps)</pre>
<dl>
	<dt>MaxProps</dt>
	<dd>
    <p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
    <p>新的容量. 如果小于自有属性的当前数量, 则使用该数量, 并释放所有未使用的空间.</p>
  </dd>
	<dt>返回值</dt>
	<dd>
    <p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
    <p>新容量.</p>
  </dd>
</dl>
<p>如果 <em>Obj</em> 的类型不正确, 则抛出异常.</p>
</div>

<div class="methodShort" id="GetCapacity"><h2>获取对象容量</h2>
<pre class="Syntax">MaxItems := <span class="func">获取对象容量</span>(Obj)</pre>
<dl>
	<dt>返回值</dt>
	<dd>
    <p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
    <p>对象内部属性的当前容量.</p>
  </dd>
</dl>
<p>如果 <em>Obj</em> 的类型不正确, 则抛出异常.</p>
</div>

</body>
</html>